; Line drawing procedure by Pablo Reda.
; Gouraud/Texture extension by Maciej Guba.
;****************************************************
line_grd_tex: ; eax=x1 ebx=y1 ecx=x2 edx=y2
              ; xmm0 - color1 argb as 4 dword  / 2 dword tex1 x y floats
              ; xmm1 - color2 argb as 4 dword  / 2 dword tex2 x y floats
              ; xmm2 - z1 as dword  float
              ; xmm3 - z2 as dword  float
              ; xmm7 - max x, max y
              ; xmm6 - min x, min y
              ; edi  - horizontal line adress
              ; xmm5  - parameters pack: Z buffer,  screen buffer,
              ;         screen width, texture ptr, as dword integer
              ;         lo -> hi: wid, texptr , zbuff, screen_ptr

        push      ebp
        mov       ebp,esp
        sub       esp,32
                                    ; xm5 lo(.wid) -> hi(.scr)   \
        .scr      equ [ebp-4]       ; .scr                        |   dont change order
        .zbuff    equ [ebp-8]       ; .zbu                        |>  !!  !!  !!
        .tex_ptr  equ [ebp-12]      ; .linetexptr                 |
        .width    equ [ebp-16]      ; .width                     /
        .h_line   equ dword[ebp-20]
        cld
        mov      .h_line,edi
        movups   .width,xmm5
        cmp      ebx,edx
        jg       .noswap
        xchg     eax,ecx
        xchg     ebx,edx
        movaps   xmm5,xmm0
        movaps   xmm0,xmm1
        movaps   xmm1,xmm5
        movaps   xmm5,xmm2
        movaps   xmm2,xmm3
        movaps   xmm3,xmm5
.noswap:
        sub      esp,16
        movlhps  xmm7,xmm6
        movups   [esp],xmm7

        push     eax ebx ecx edx
        movups   xmm7,[esp]
        cvtdq2ps xmm7,xmm7
        pcmpeqd  xmm3,xmm3
        movhlps  xmm6,xmm7
        psrld    xmm3,1
        subps    xmm7,xmm6
      
        andps    xmm7,xmm3 ;[abs_mask]  ; 0x7fff
        add      esp,16

        movaps   xmm6,xmm7
        shufps   xmm6,xmm6,01010101b
        maxps    xmm7,xmm6   ; xmm7 - delta
        shufps   xmm7,xmm7,0
        movaps   xmm6,xmm3
        rcpps    xmm7,xmm7
        subps    xmm6,xmm2
        mulps    xmm6,xmm7   ; xmm6 - delta z
        movaps   xmm5,xmm1
        subps    xmm5,xmm0
        mulps    xmm5,xmm7   ; xmm5 - delta col argb

        movups   xmm3,[esp]
        movhlps  xmm4,xmm3
        add      esp,16
        shufps   xmm4,xmm4,00000101b  ; xm4 - lo hi -> min x  min x miny miny
        shufps   xmm3,xmm3,00000101b  ; xm3 - lo hi -> max x  max x maxy maxy

        shl      eax,16
        shl      ecx,16
        sub      eax,ecx
        push     ebx
        push     edx
        sub      ebx,edx
        inc      ebx
        push     ebx
        push     eax

        cvtpi2ps xmm7,[esp]
        movaps   xmm6,xmm7
        shufps   xmm6,xmm6,11111101b
        rcpss    xmm6,xmm6
        mulps    xmm7,xmm6
        cvtss2si eax,xmm7
        add      esp,8

        mov   esi,eax
      ;  neg   cx
        add   ecx,$7fff
        pop   ebx
        pop   edx
.lineas:
        mov   eax,ecx
        add   eax,esi
        push  ebx
        push  eax
        push  edx
        shr   ecx,16
        shr   eax,16
        call  .h_line  ;.horizontal_grd/ tex/ plain
        pop   edx
        pop   ecx
        pop   ebx
;        cmp   edx,ebx
;        je    @f
        inc   ebx
        cmp   ebx,edx
        jle   .lineas
;      @@:  
        mov   esp,ebp
        pop   ebp
        ret

horizontal_grd:  ; eax=x1 ebx=y1 ecx=x2

        .scr      equ [ebp-4]                     ; .scr
        .zbuff    equ [ebp-8]                     ; .zbu
        .tex_ptr  equ [ebp-12]                    ; .linetexptr
        .width    equ [ebp-16]                    ; .width

        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16
        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3

        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .en

        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
.m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
.nn:
        imul     ebx,.width
        add      eax,ebx
        shl      eax,2
        mov      edi,.scr
        add      edi,eax

        push     eax
        push     ebx
        mov      ebx,.zbuff
        add      edx,eax
     ;  lea      ebx,[ebx+eax*4]
.l:
        movaps   xmm7,xmm2    ; xmm2 - cur z
        cmpnltss xmm7,[ebx]
        movd     eax,xmm7
        or       eax,eax
        jnz      @f
        movaps   xmm7,xmm0    ; xmm0 - cur col
        cvtps2dq xmm7,xmm7
        packssdw xmm7,xmm7
        packuswb xmm7,xmm7
        movd     [edi],xmm7
      @@:
        addps    xmm2,xmm6
        addps    xmm0,xmm5
        add      edi,4
        loop     .l
        pop      ebx
        pop      eax
.en:
        ret

horizontal_tx:  ; eax=x1 ebx=y1 ecx=x2
        .scr      equ [ebp-4]                     ; .scr
        .zbuff    equ [ebp-8]                     ; .zbu
        .tex_ptr  equ [ebp-12]                    ; .linetexptr
        .width    equ [ebp-16]                    ; .width

        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16
        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3
        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .en1
        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
    .m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
    .nn:
        imul     ebx,.width
        add      eax,ebx
        shl      eax,2
        mov      edi,.scr
        add      edi,eax
        push     eax
        push     ebx
        mov      ebx,.zbuff
        add      ebx,eax
    .l:
        movaps   xmm7,xmm2     ; xmm2 - cur z
        cmpnltss xmm7,[ebx]
        movd     eax,xmm7
        or       eax,eax
        jnz      @f
        movss    [ebx],xmm2
        movaps   xmm7,xmm0    ; xmm0 - cur col
        cvtps2dq xmm7,xmm7
    ;    xmm7  - cur tex coord
        sub      esp,8
        movlps   [esp],xmm7
        pop      eax edx
        shl      eax,TEX_SHIFT
        add      eax,edx
        shl      eax,2
        and      eax,TEXTURE_SIZE
        add      eax,.tex_ptr
        mov      eax,[eax]
        mov      [edi],eax
     @@:
        add      edi,4
        add      ebx,4
        addps    xmm0,xmm5
        addps    xmm2,xmm6
        loop     .l
        pop      ebx
        pop      eax
    .en1:
        ret
if 0
grid_horizontal:
; Checks indexes of tris, its ptrs resides in
; cells of grid.
        .grid     equ [ebp-4]  ; grid array with ptr to indices
        .indices  equ [ebp-8]  ; ptr to destination readed indices
        .counter  equ [ebp-12] ; should be not changed in whole line_grd_tex proc
        .width    equ [ebp-16] ; width

        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16
        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3
        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .en1
        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
    .m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
    .nn:
        imul     ebx,.width
        add      eax,ebx
        shl      eax,2
        mov      edi,eax
        push     eax
        push     ebx
        add      edi,.grid
    .l:

        mov      edx,[edi]
        cmp      edx,-1
        je       .br            ; no pointer
        or       edx,edx
        jz       .br            ; no pointer
        mov      edx,[edx]
      @@:
        mov      eax,[edx]
        cmp      eax,-1
        je       .br            ; break
        mov      ebx,.counter   ; indices can be not distinct = ..
        mov      esi,.indices   ; .. = bigger .indices list
        shl      ebx,2
        add      esi,ebx
        mov      [esi],eax      ; eax curr index
        inc      dword .counter
        add      edx,4
        jmp      @b
      .br:
        add      edi,4
        loop     .l
        pop      ebx
        pop      eax
    .en1:
        ret

end if
if 0

vox_horizontal:
; checks indexes of tris, its ptrs resides in
; cells of voxels.
        .vox      equ [ebp-4]  ; .vox array with plane slices
        .indices  equ [ebp-8]  ; .ptr to readed indices
        .counter  equ [ebp-12] ; .should be not changed in whole line_grd_tex proc
        .width    equ [ebp-16] ; .width

        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16
        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3
        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .en1
        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
    .m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
    .nn:
        imul     ebx,.width
        add      eax,ebx
        shl      eax,2
        mov      edi,eax
        push     eax
        push     ebx
    .l:
                               ; xmm2 - cur z
                               ; 'z' coord should be in 0 .. width range
        cvtss2si eax,xmm2      ; eax = number of plane slice
        shl      eax,4
        add      eax,.vox
        mov      eax,[eax]     ; ptr to concrete plane
        add      eax,edi       ; edi = pos related to x, y
                               ; [eax] = ptr to indices related to curr voxel
      @@:                      ; -1 terminated
        mov      edx,[eax]
        cmp      edx,-1
        je       @f
        mov      ebx,.counter  ; indices can be not distinct = ..
        mov      esi,.indices  ; .. = bigger .indices list
        shl      ebx,2
        add      esi,ebx
        mov      [esi],edx
        inc      dword .counter
        add      eax,4
        jmp      @b
      @@:
        add      edi,4
        addps    xmm2,xmm6
        loop     .l
        pop      ebx
        pop      eax
    .en1:
        ret

end if
plain_horizontal:  ; eax=x1 ebx=y1 ecx=x2
        .scr      equ [ebp-4]     ; .scr
        .zbuff    equ [ebp-8]     ; .zbu
        .tex_ptr  equ [ebp-12]    ; .linetexptr
        .width    equ [ebp-16]    ; .width

        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16
        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3
        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .l
        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
.m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
.nn:
        imul     ebx,.width
        add      eax,ebx
        mov      edi,.scr
        lea      edi,[edi+eax*4]
        mov      eax,.tex_ptr  ; .tex_ptr = col
        rep      stosd
.l:
        ret

if 0
plain_horizontal256:
        .scr      equ [ebp-4]      ; .scr
        .zbuff    equ [ebp-8]      ; .zbu
        .tex_ptr  equ [ebp-12]     ; .linetexptr
        .width    equ [ebp-16]     ; .width
        push     eax ecx ebx ebx
        movups   xmm7,[esp]
        movaps   xmm1,xmm7
        add      esp,16

        pcmpgtd  xmm1,xmm4
        pcmpgtd  xmm7,xmm3
        xorps    xmm7,xmm1
        pmovmskb edi,xmm7    ; clipping
        cmp      di,0xffff
        jnz      .l

        cmp      ecx,eax
        jg       .m
        xchg     ecx,eax
.m:
        sub      ecx,eax
        jnz      .nn
        inc      ecx
.nn:
        imul     ebx,.width
        add      eax,ebx
        mov      edi,.scr
        lea      edi,[edi+eax]
        mov      eax,.tex_ptr  ; xm3 - col
        rep      stosd
.l:
        ret
end if
